﻿using Basic.FlowDAL;
using Basic.FlowModel;
using Basic.FlowModel.DB;
using Basic.FlowModel.Flow;
using Basic.FlowModel.Node;
using Basic.FlowRemoteModel;
using Basic.FlowRemoteModel.Flow.Model;
using WeDonekRpc.Helper;
using WeDonekRpc.Model;

namespace Basic.FlowCollect.lmpl
{
    internal class FlowCollect : IFlowCollect
    {
        private readonly IFlowListDAL _BasicDAL;

        public FlowCollect ( IFlowListDAL basicDAL )
        {
            this._BasicDAL = basicDAL;
        }
        public DBFlowList Get ( long id )
        {
            return this._BasicDAL.Get(id);
        }
        public long? GetDefFormId ( long flowId )
        {
            return this._BasicDAL.Find(flowId, a => a.DefFormId);
        }
        public void Delete ( DBFlowList source )
        {
            this._BasicDAL.Delete(source.Id);
        }
        public long Add ( FlowAdd add )
        {
            if ( this._BasicDAL.IsExists(c => c.FlowName == add.FlowName && c.VerNum == ConstDic.FlowInitVer) )
            {
                throw new ErrorException("flow.name.repeat");
            }
            return this._BasicDAL.Add(add);
        }
        public long Save ( FlowBodyAdd add )
        {
            return this._BasicDAL.Save(add);
        }
        public bool Set ( DBFlowList source, FlowSet set )
        {
            if ( source.Status == FlowStatus.启用 )
            {
                throw new ErrorException("flow.status.error");
            }
            if ( source.FlowName != set.FlowName && this._BasicDAL.IsExists(c => c.FlowName == set.FlowName && c.VerNum == source.VerNum) )
            {
                throw new ErrorException("flow.name.repeat");
            }
            return this._BasicDAL.Update(source, set);
        }
        public Result[] Query<Result> ( FlowQueryParam query, IBasicPage paging, out int count ) where Result : class
        {
            return this._BasicDAL.Query<Result>(query, paging, out count);
        }

        public Result[] GetChildren<Result> ( long sourceId ) where Result : class, new()
        {
            return this._BasicDAL.GetChildren<Result>(sourceId);
        }
        public Result[] GetChildren<Result> ( long[] sourceId ) where Result : class, new()
        {
            return this._BasicDAL.Gets<Result>(a => a.SourceId != null && sourceId.Contains(a.SourceId.Value));
        }
        public Result Get<Result> ( long id ) where Result : class, new()
        {
            return this._BasicDAL.Get<Result>(id);
        }

        public Dictionary<long, string> GetFlowName ( long[] ids )
        {
            return this._BasicDAL.Gets(ids, a => new
            {
                a.Id,
                a.FlowName
            }).ToDictionary(a => a.Id, a => a.FlowName);
        }

        public string GetFlowName ( long id )
        {
            return this._BasicDAL.Get(id, a => a.FlowName);
        }
        public bool Enable ( DBFlowList flow, NodeSet[] sets )
        {
            if ( flow.Status == FlowStatus.启用 )
            {
                return false;
            }
            this._BasicDAL.Enable(flow, sets);
            return true;
        }
        public bool SetStatus ( DBFlowList flow, FlowStatus status )
        {
            if ( flow.Status == status )
            {
                return false;
            }
            this._BasicDAL.SetStatus(flow, status);
            return true;
        }

        public bool CheckIsExists ( string name, string ver )
        {
            return this._BasicDAL.IsExists(c => c.FlowName == name && c.VerNum == ver);
        }

        public string GetMaxVer ( long id )
        {
            return this._BasicDAL.GetMaxVer(id);
        }

        public long GetFlowId ( long flowId, string ver )
        {
            var source = this._BasicDAL.Get(a => a.Id == flowId, a => new
            {
                a.SourceId,
                a.VerNum
            });
            if ( source.VerNum == ver )
            {
                return flowId;
            }
            long sourId = source.SourceId.GetValueOrDefault(flowId);
            return this._BasicDAL.Get(a => a.SourceId == sourId && a.VerNum == ver, a => a.Id);
        }
    }
}
